package com.smallstep.hystrix.exceptions;

import com.smallstep.hystrix.enums.HystrixKeyEnum;
import com.smallstep.hystrix.properties.FFHystrixProperties;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.ResourceAccessException;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 李俊
 */
public class FallbackIgnore implements IFallbackIgnore {

    private List<HttpStatusCompare> httpStatusCompares = new ArrayList();

    public FallbackIgnore() {
    }


    @PostConstruct
    private void initHttpStatusCompares() {
        List<FallbackIgnore.HttpStatusCompare> tempHttpStatusCompares = new ArrayList();
        String ignoreHttpStatus = FFHystrixProperties.getProperty(HystrixKeyEnum.FF_HYSTRIX_CLIENT_FALLBACK_IGNORE_HTTPSTATUS);
        if (StringUtils.isNotEmpty(ignoreHttpStatus)) {
            String[] strs = ignoreHttpStatus.split(",");
            for (int i = 0; i < strs.length; i++) {
                String str = strs[i];
                str = str.trim();
                if (str.contains("-")) {
                    String[] subStrs = str.split("-");
                    tempHttpStatusCompares.add(new FallbackIgnore.HttpStatusCompare(Integer.parseInt(subStrs[0]), Integer.parseInt(subStrs[1])));
                } else {
                    tempHttpStatusCompares.add(new FallbackIgnore.HttpStatusCompare(Integer.parseInt(str), Integer.parseInt(str)));
                }
            }
        }
        this.httpStatusCompares = tempHttpStatusCompares;
    }

    @Override
    public boolean isFallbackIgnore(Exception e) {
        if (e instanceof HttpClientErrorException) {
            HttpClientErrorException httpClientError = (HttpClientErrorException)e;
            int statusCode = httpClientError.getStatusCode().value();
            for (int i = 0; i < httpStatusCompares.size(); i++) {
                if (httpStatusCompares.get(i).isMatch(statusCode)) {
                    return true;
                }
            }


        }

        return false;
    }

    class HttpStatusCompare {
        private int min;
        private int max;

        public boolean isMatch(int httpStatus) {
            return this.min <= httpStatus && httpStatus <= this.max;
        }

        public HttpStatusCompare(int min, int max) {
            this.min = min;
            this.max = max;
        }
    }
}
